#include <klib.h>
#include <klib-macros.h>
#include <stdint.h>

#if !defined(__ISA_NATIVE__) || defined(__NATIVE_USE_KLIB__)

size_t strlen(const char *s) {
	size_t cnt=0;
	while (s[cnt] != '\0')
	{
		cnt ++;
	}
	return cnt;
}

char *strcpy(char *dst, const char *src) {
	assert(src  && dst );
	char* temp = dst;
	while (*src)
	{
		*dst++ = *src++;
	}
	return temp;
}

char *strncpy(char *dst, const char *src, size_t n) {
	assert(src && dst);
  	char* temp = dst;
	while (n--)
	{
		*dst++ = *src++;
	}
	return temp;
}

char *strcat(char *dst, const char *src) {
	assert(src  && dst );
	char *temp = dst;
	while (*dst)
	{
		dst++;
	}
	while (*src)
	{
		*dst++ = *src++;
	}
	return temp;
}

int strcmp(const char *s1, const char *s2) {
	assert(s1 && s2);
	int temp = 0;
	const char * temp1=s1;
	const char * temp2=s2;
	while (*temp1 != '\0')
	{
		if(*temp1 > *temp2){
			temp = 1;
			break;
		}
		else if(*temp1 < *temp2){
			temp = -1;
			break;
		}
		temp1++;
		temp2++;
	}
	return temp;
}

int strncmp(const char *s1, const char *s2, size_t n) {
	assert(s1 && s2);
	int temp = 0;
	size_t cnt=0;
	const char * temp1=s1;
	const char * temp2=s2;
	while (*temp1 || *temp2)
	{
		if(*temp1 > *temp2){
			temp = 1;
			break;
		}
		else if(*temp1 < *temp2){
			temp = -1;
			break;
		}
		if(cnt == n)
			break;
		cnt ++;
		temp1++;
		temp2++;
	}
	return temp;
}

void *memset(void *s, int c, size_t n) {
	assert(s);
	char *temp = (char *)s;
	for (size_t i = 0; i < n; i++)
	{
		*temp++ = c;
	}
	return s;
}

void *memmove(void *dst, const void *src, size_t n) {
	assert(dst && src);
    void* ret=dst;
	if (dst < src)
	{
		while (n--)//前->后
		{
			*(char*)dst = *(char*)src;
			dst = (char*)dst + 1;
			src = (char*)src + 1;
		}
	}
	else
	{
		while (n--)//后->前
		{
			*((char*)dst+n) = *((char*)src + n);
		}
	}
	return ret;
}

void *memcpy(void *out, const void *in, size_t n) {
	assert(out && in );
	void* ret = out;
	while (n--)
	{
		*(char*)out = *(char*)in;
		out = (char*)out + 1;
		in = (char*)in + 1;
	}
	return ret;
}

int memcmp(const void *s1, const void *s2, size_t n) {
	assert(s1 && s2);
	int temp = 0;
	while (n--)
	{
		if(*(char*)s1 > *(char*)s2){
			temp = 1;
			break;
		}
		else if(*(char*)s1 < *(char*)s2){
			temp = -1;
			break;
		}
		s1 = (char*)s1 + 1;
		s2 = (char*)s2 + 1;
	}
	return temp;
}

#endif
